package kotlinLearning.catherineliujj.main.start

import sun.security.util.Length
import java.lang.Exception
import java.lang.IllegalStateException
import java.math.BigDecimal
import java.nio.file.Files
import java.nio.file.Paths

/**
 * 开始  习惯用法
 */
fun main(){
    println("Hello World!!!")
    // 数据类和类的区别
    /**
     * 数据类
     * toString，获取整个数据类的具体属性值，普通类打印的是地址
     * components，获取对应属性的值（初始值，copy后的值无法获取）
     * copy，可以用来修改具体属性的值（变量名 = 值）
     * 重写了hashCode方法，不再比较对象引用，而是比较对象的值
     */
/*    var usage = UsedUsage("Amy", "12346789@qq.com")
    var dataPerson = DataPerson("Bob", 12)
    var person = Person("Bob", 12)
    println(usage.name + "=====" + usage.email)
    println(dataPerson.name + "=====" + dataPerson.age)
    println(person.name + "=====" + person.age)

    println(dataPerson.toString() + "==" + dataPerson.copy(dataPerson.name, 18) + "---" + dataPerson.copy(age = 20)
    + "===" + dataPerson.component1() + "---" + dataPerson.component2()
    )
    println(person.toString())*/

/*    val text = """
        First Line
        | Second Line
        |Third Line
        """.trimMargin()
    println(text)*/

/*    println(DefaultParam())
    println(DefaultParam(1))
    println(DefaultParam(b = "yes"))*/

/*    val filterList = FilterList(listOf("apple", "absorbed", "banana", "car", "award"))
    println(filterList)
    val filterIntList = FilterIntList(listOf(18, 20, 19, 26, 30, 20, 16, 18))
    println(filterIntList)*/

/*//    val map = mapOf(Pair("a", 1), Pair("c", 15), Pair("b", 2), Pair("a", 6))
    val map = mapOf("a" to 1, "v" to 2)
    val value = map["c"]
    for ((k, v) in map){
        println("$k -> $v")
    }
    println(value)*/

/*    // todo 延迟属性
    val p : String by lazy {
//        println("computed!")
        "Hello" }
    println(p)
    val i : Int by lazy { 6 }
    println(i)*/

/*    // 扩展函数
   println("Convert this to camelcase".spaceToCamelCase())*/

/*    // 创建单例
    val resource = Resource.name
    val maxOf = Resource.maxOf("22", "20")
    println("${resource}, ${maxOf}")*/

/*    // If not null 缩写
    val file = File("test").listFiles()
    println(file?.size)
    // If not null and else 缩写
    println(file?.size ?: "Empty")  //  如果[file（可空）的大小]（可空）为空，打印“Empty”
    // if null 执行一个语句
    val values = mapOf("phone" to "2222294", "email" to "123456789@qq.com")
    val email = values["email"] ?: throw IllegalStateException("Email is missing!")
    println(email)
    // 在可能会空的集合中取第一元素
//    val emails = listOf<String>()
//    val emails = null
    val emails = listOf("cc", "aa", "bb")
    val mainEmail = emails.firstOrNull() ?: "unExit"
    println(mainEmail)
    // if not null 执行代码
    emails?.let {
        // 假如emails不为null，代码会执行到此处
        println("List is not Empty")
    }
    // 如果该值或其转换结果为空，那么返回defaultValue
    val info = mapOf<String, String>()
    val mapped = info?.let { transformValue(it) } ?: "defaultValue"
//    val mapped = values?.let { transformValue(it) } ?: "defaultValue"
    println(mapped)*/

/*//    val validColor = transform("red")
    val validColor = transform("Red")
    println(validColor)*/
    // todo try/catch
//    testTryCatch(transform("red"))

//    ifNum(6)

/*    val arrayOfMinusOnes = arrayOfMinusOnes(6)
    println(arrayOfMinusOnes.forEach { println(it) })*/

/*    val singleFun = singleFun()
    println(singleFun)
    val singleFun2 = singleFun2()
    println(singleFun2)
    val singleFun3 = singleFun3("red")
    println(singleFun3)*/

/*    // 对一个对象实例调用多个方法 （with）
    val turtle = Turtle()
    with(turtle){
        penDown()
        for (i in 1..4){
            forward(i * 10.0)
            turn(i * 9.0)
        }
        penUp()
    }*/

    // todo  配置对象的属性（apply）
/*    val rectangle = Rectangle(3.0, 3.0)
    println(rectangle.isSquare)*/
/*    val rectangle2 = Rectangle(3.0, 6.0).apply {
        height = 2.0
        length = 2.0
    }
    println(rectangle2.isSquare)*/

    // todo Java 7 的 try with resources
/*    val newInputStream = Files.newInputStream(Paths.get("/some/file.txt"))
    newInputStream.buffered().reader().use { reader -> println(reader.readText()) }*/

//    printLnList(listOf("abc", 111, 1.0))

    // todo 交换两个变量
//    changeNum()

    // TODO()：将代码标记为不完整
//    calcTaxes()
}
// 构造函数一定要指定变量是val还是var
data class UsedUsage(val name: String, val email: String)
class Person(val name: String, val age: Int)
data class DataPerson(val name: String, val age: Int)

fun DefaultParam(a: Int = 0, b: String = "b"): String{
    return a.toString() + b
}

fun FilterList(list: List<String>): List<String> {
    val filterList = list.filter { it.startsWith("a") }
        .sortedBy { it }
        .map { it.toUpperCase() }
        .map { it.toLowerCase() }
        .subList(1, 3)
//    println(list.toString() + "=========" + list.size)
    return filterList
}
fun FilterIntList(list: List<Int>): List<Int> {
/*    val filterList = list.filter { x -> x >= 20 }
        .sortedBy { it }*/
/*    val filterList = list.filter { it >= 20 }
        .sortedBy { it }*/
/*    val filterList = list.filter { it in 1..20 }
        .sortedBy { it }*/
/*    val filterList = list.filter { it in 1 until 20 }
        .sortedBy { it }*/
/*    val filterList = list.filter { it !in 1 .. 20 }
        .sortedBy { it }*/
    val filterList = list.filter { it !in 1 until 20 }
        .sortedBy { it }
    return filterList
}

fun String.spaceToCamelCase(){
    println(toUpperCase())
}

// 创建单例
object Resource {
    val name = "Amy"
    fun maxOf(str: String, str2: String): String? {
        return if (str > str2) str else str2
    }
}

fun transformValue(string: Map<String, String>) : String? {
    return string["phone"]
}

fun transform(color: String): Int{
    return when(color){
        "Red" -> 0
        "Green" -> 1
        "yellow" -> 2
        else -> throw IllegalStateException("Invalid color param value")
    }
}

fun testTryCatch(str: Int){
    val result = try {
        str
    } catch (e : Exception){
        throw IllegalStateException(e)
    }
    println(result)
}

fun ifNum(param: Int){
    val result = if (param == 1) {
        "one"
    } else if (param == 2){
        "two"
    } else {
        "other num"
    }
    println(result)
}

fun arrayOfMinusOnes(size:Int): IntArray{
    return IntArray(size).apply { fill(6) }
}

//  单表达式函数
fun singleFun() = 66
fun singleFun2(): Int{
    return 66
}
fun singleFun3(colors: String) = when(colors){
    "Red" -> 0
    "red" -> 1
    else -> 2
}

class Turtle {
    fun penDown() { println("Down")}
    fun penUp() { println("Up")}
    fun turn(degree: Double) { println(degree * degree)}
    fun forward(pixels: Double) { println(pixels + pixels)}
}

fun printLnList(list: List<Any>){
    list.forEach{
        print(" -> ${it}")
    }
}

fun changeNum(){
    var a = 1
    var b = 2
    println("a = ${a}, b = ${b}")
    a = b.also { b = a }
    print("a = ${a}, b = ${b}")
}

fun calcTaxes() :BigDecimal = TODO("Waiting for feedback from accounting")